package com.ht.api.task;

import java.util.ArrayList;
import java.util.List;

import javax.sql.DataSource;

import com.ht.api.db.Db;
import com.ht.api.db.DbConfig;
import com.ht.api.db.Entity;
import com.ht.api.db.StreamLoadConfig;
import com.ht.api.db.exception.HtException;
import com.ht.api.db.task.HtTaskExecutor;
import com.ht.api.db.task.Plan;
import com.ht.api.db.task.TaskHandler;
import com.ht.api.open.OpenUtil;

import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;

/**
 * 启动客户接替任务
 * @author asq
 * @createTime 2025年3月13日 15:40:40
 */
@Slf4j
public class TransferStartTask implements TaskHandler{
	/** 接口ID：分配在职成员的客户 */
	private static final long API_ID = 1899984469281083392L;
	/** 接口ID：分配离职成员的客户 */
	private static final long API_ID_DIMISSION = 1899990942883123200L;
	/** 接替任务每次处理的条数 */
	private static final int SIZE = 5;

	@Override
	public String getName() {
		return "启动客户接替任务";
	}

	@Override
	public boolean handler(JSONObject requestParam, String groupId, long taskId) {
		// 获取数据源
		long tenantId = requestParam.getLong("tenant_id");
		DataSource ds = DbConfig.useTenantDb(tenantId);

		// 查询客服接替任务
		String mainId = requestParam.getStr("main_id");
		Entity wxTransferUser = Db.createSqlParser("wx_transfer_user").findById(ds, mainId);
		List<Entity> wxTransferUserItemList = Db.createSqlParser("wx_transfer_user_item")
				.where("transfer_id", mainId).query(ds);
		if (wxTransferUserItemList.isEmpty()) {
			throw new HtException("未分配要接替的客户，不能启动任务~");
		}
		
		// 判断继承类别 0：在职继承；1：离职继承
		int type = wxTransferUser.getInt("type");
		long apiId = type == 0 ? API_ID : API_ID_DIMISSION;

		Entity wxTransferUserUpdate = Entity.create("wx_transfer_user");
		wxTransferUserUpdate.setMainId(wxTransferUser.getMainId());

		// 调用企微接口，每次处理100条，全部处理完后，再生成定时任务
		int page = 1;
		List<Entity> externalUseridArr = getSubList(wxTransferUserItemList, page);
		while (externalUseridArr != null && !externalUseridArr.isEmpty()) {
			boolean isSucc = call(requestParam, ds, wxTransferUser, externalUseridArr, apiId);
			if (isSucc) {
				wxTransferUserUpdate.set("status", 2);
			} else {
				wxTransferUserUpdate.set("status", 3);
			}
			externalUseridArr = getSubList(wxTransferUserItemList, ++page);
		}

		Db.insert(ds, wxTransferUserUpdate);

		// 24小时零5分钟后，调用接口：查看客户接替状态
		log.info("[TransferStartTask]客户接替完毕，启动定时任务，24小时后查看最终接替状态，wx_transfer_user表mainId：{}", mainId);
		int startTime = (int) (System.currentTimeMillis() / 1000) + (60 * 60 * 24) + (300);
		Plan plan = Plan.create().at(startTime);
		HtTaskExecutor.submitTask(requestParam, new TransferQueryTask(), plan);
		
		return true;
	}

	/**
	 * 受企微接口限制，每次处理100条
	 * @param wxTransferUserItemList 要处理的客服接替明细表的全部数据
	 * @param page 页码
	 * @return
	 */
	private List<Entity> getSubList(List<Entity> wxTransferUserItemList, int page) {
		int formIndex = (page - 1) * SIZE;
		int toIndex = formIndex + SIZE;
		toIndex = Math.min(toIndex, wxTransferUserItemList.size());
		if (formIndex < toIndex) {
			return wxTransferUserItemList.subList(formIndex, toIndex);
		} else {
			return null;
		}
	}
	
	/**
	 * 调用企微接口，并处理本地数据
	 * @param requestParam 执行任务时传进来的参数
	 * @param ds 数据源
	 * @param wxTransferUser 客服接替表数据
	 * @param wxTransferUserItemList 客服接替明细表数据
	 * @param apiId 应用ID
	 */
	private boolean call(JSONObject requestParam, DataSource ds, Entity wxTransferUser,
			List<Entity> wxTransferUserItemList, long apiId) {
		boolean isSucc = true;

		String appId = wxTransferUser.getStr("appid");
		JSONObject param = JSONUtil.createObj();
		param.set("handover_userid", wxTransferUser.getStr("handover_userid"));
		param.set("takeover_userid", wxTransferUser.getStr("takeover_userid"));
		param.set("external_userid", getExternalUseridArr(wxTransferUserItemList));
		param.set("transfer_success_msg", wxTransferUser.getStr("transfer_success_msg"));
		String str = OpenUtil.call(appId, apiId, param);

		int type = wxTransferUser.getInt("type");
		String handoverUserid = wxTransferUser.getStr("handover_userid");

		// 如果企微接口调用成功，则操作本地数据库
		JSONObject obj = JSONUtil.parseObj(str);
		if (obj.getInt("errcode") == 0) {
			// 更新数据库
			updateToDb(ds, wxTransferUser, wxTransferUserItemList, obj, appId);
		} else {
			isSucc = false;
			log.error("企微接口返回错误：{}", obj.getStr("errmsg"));
			
			// 如果请求接口失败，则更新wx_transfer_user的status=3，和errcode，并把对应的wx_transfer_user_item的status更新为5
			List<Entity> dataList = new ArrayList<>();

			Entity wxTransferUserUpdate = Entity.create("wx_transfer_user");
			wxTransferUserUpdate.setMainId(wxTransferUser.getMainId());
			wxTransferUserUpdate.set("status", 3);
			wxTransferUserUpdate.set("errcode", obj.getInt("errcode"));
			wxTransferUserUpdate.set("fail_cnt", wxTransferUserItemList.size());
			dataList.add(wxTransferUserUpdate);
			
			for (Entity entry : wxTransferUserItemList) {
				Entity wxTransferUserItemUpdate = Entity.create("wx_transfer_user_item");
				wxTransferUserItemUpdate.setMainId(entry.getMainId());
				wxTransferUserItemUpdate.set("status", 5);
				wxTransferUserItemUpdate.set("errcode", obj.getInt("errcode"));
				wxTransferUserItemUpdate.set("execute_time", DateUtil.now());
				dataList.add(wxTransferUserItemUpdate);


				if (type == 1) { // 离职继承处理
					Entity workuserDimissionExternal = Entity.create("wx_workuser_dimission_external");
					workuserDimissionExternal.set("appid", appId);
					workuserDimissionExternal.set("handover_userid", handoverUserid);
					workuserDimissionExternal.set("external_userid", entry.getStr("external_userid"));
					workuserDimissionExternal.set("status", 5);

					dataList.add(workuserDimissionExternal);
				}
			}

			if (type == 1) {
				Entity workuserDimission = Entity.create("wx_workuser_dimission");
				workuserDimission.set("appid", appId);
				workuserDimission.set("handover_userid", handoverUserid);
				workuserDimission.set("wait_cnt", wxTransferUserItemList.size());

				dataList.add(workuserDimission);
			}

			Db.insertBatchWithStream(DbConfig.getStreamLoadConfigByDataSource(ds), dataList);
		}

		return isSucc;
	}

	/**
	 * 获取客服接替明细表中的external_userid数组
	 * @param wxTransferUserItemList
	 * @return
	 */
	private JSONArray getExternalUseridArr(List<Entity> wxTransferUserItemList) {
		JSONArray arr = JSONUtil.createArray();
		wxTransferUserItemList.stream().forEach(item -> {
			arr.add(item.getStr("external_userid"));
		});
		return arr;
	}


	/**
	 * 更新数据库
	 * @param ds 数据源
	 * @param wxTransferUser 客服接替表
	 * @param wxTransferUserItemList 客服接替明细表
	 * @param wwxResult 企微接口返回结果
	 * @param appid 应用ID
	 */
	private void updateToDb(DataSource ds, Entity wxTransferUser, List<Entity> wxTransferUserItemList, 
			JSONObject wwxResult, String appid) {
		List<Entity> dbList = new ArrayList<>();
		String handoverUserid = wxTransferUser.getStr("handover_userid");
		String takeoverUserid = wxTransferUser.getStr("takeover_userid");
		int type = wxTransferUser.getInt("type");

		int failCnt = 0;

		//继承结果处理
		JSONArray customers = wwxResult.getJSONArray("customer");
		for (int i = 0; i < customers.size(); i++) {
			JSONObject customer = customers.getJSONObject(i);

			String externalUserid = customer.getStr("external_userid");
			int errcode = customer.getInt("errcode");

			Entity transferUserItem = Entity.create("wx_transfer_user_item");
			transferUserItem.set("transfer_id", wxTransferUser.getMainId());
			transferUserItem.set("handover_userid", handoverUserid);
			transferUserItem.set("takeover_userid", takeoverUserid);
			transferUserItem.set("external_userid", externalUserid);
			transferUserItem.set("execute_time", DateUtil.now());

			if (errcode == 0) {
				transferUserItem.set("status", 1);
			} else {
				transferUserItem.set("status", 6);
				transferUserItem.set("errcode", errcode);
			}

			dbList.add(transferUserItem);

			if (type == 1) { // 离职继承处理
				Entity workuserDimissionExternal = Entity.create("wx_workuser_dimission_external");
				workuserDimissionExternal.set("appid", appid);
				workuserDimissionExternal.set("handover_userid", handoverUserid);
				workuserDimissionExternal.set("external_userid", externalUserid);

				if (errcode == 0) {
					workuserDimissionExternal.set("status", 1);
				} else {
					workuserDimissionExternal.set("status", 4);
					workuserDimissionExternal.set("errcode", errcode);

					failCnt++;
				}

				dbList.add(workuserDimissionExternal);
			}
		}

		if (type == 1) {
			Entity workuserDimission = Entity.create("wx_workuser_dimission");
			workuserDimission.set("appid", appid);
			workuserDimission.set("handover_userid", handoverUserid);
			workuserDimission.set("status", 1);
			workuserDimission.set("fail_cnt", failCnt);

			dbList.add(workuserDimission);
		}

		Entity wxTransferUserUpdate = Entity.create("wx_transfer_user");
		wxTransferUserUpdate.setMainId(wxTransferUser.getMainId());
		wxTransferUserUpdate.set("fail_cnt", failCnt);
		dbList.add(wxTransferUserUpdate);

		// 保存所有数据
		StreamLoadConfig streamLoadConfig = DbConfig.getStreamLoadConfigByDataSource(ds);
		Db.insertBatchWithStream(streamLoadConfig, dbList);
	}
}
